package net.stogi.unicore.beyond.ui.client.taskrunner.runnermenu;

import java.util.List;

import net.stogi.common.gwt.dispatch.client.core.ActionManager;
import net.stogi.common.gwt.frame.client.core.EventBus;
import net.stogi.common.gwt.frame.client.mvp.AbstractPresenter;
import net.stogi.common.mvp.core.behavior.Behavior;
import net.stogi.common.mvp.core.behavior.BehaviorWithValue;
import net.stogi.unicore.beyond.api.model.TaskDefinition;
import net.stogi.unicore.beyond.ui.client.taskrunner.taskinstance.OpenTaskInstanceEvent;
import net.stogi.unicore.beyond.ui.shared.common.action.model.LoadTaskDefinitionsAction;
import net.stogi.unicore.beyond.ui.shared.common.action.model.LoadTaskDefinitionsResult;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;

class TaskSelectorPresenter extends AbstractPresenter {

	private TaskSelectorView taskSelectorView;

	private List<TaskDefinition> taskDefinitions;

	private TaskDefinition selectedTaskDefinition;

	public TaskSelectorPresenter(TaskSelectorView taskSelectorView, ActionManager actionManager, EventBus eventBus) {
		super(actionManager, eventBus);
		this.taskSelectorView = taskSelectorView;
		initBehavior();
		initHandlers();
	}

	@Override
	protected void initBehavior() {
		taskSelectorView.setCancelBehavior(new Behavior() {

			@Override
			public void behave() {
				taskDefinitions = null;
				taskSelectorView.disapper();
			}
		});
		taskSelectorView.setOpenBehavior(new Behavior() {

			@Override
			public void behave() {
				if (selectedTaskDefinition != null) {
					eventBus.fireEvent(new OpenTaskInstanceEvent(selectedTaskDefinition));
					selectedTaskDefinition = null;
					taskDefinitions = null;
					taskSelectorView.disapper();
				}
			}
		});
		taskSelectorView.setTaskDoubleClickedBehavior(new BehaviorWithValue<String>() {

			@Override
			public void behave(String value) {
				if (value != null) {
					TaskDefinition taskDefinition = internalGetTaskDefinitionByName(value);
					eventBus.fireEvent(new OpenTaskInstanceEvent(taskDefinition));
					selectedTaskDefinition = null;
					taskDefinitions = null;
					taskSelectorView.disapper();
				}
			}
		});
		taskSelectorView.setTaskSelectedBehavior(new BehaviorWithValue<String>() {

			@Override
			public void behave(String value) {
				selectedTaskDefinition = internalGetTaskDefinitionByName(value);
			}
		});
	}

	@Override
	protected void initHandlers() {
		eventBus.addHandler(OpenTaskSelectorEvent.TYPE, new OpenTaskSelectorHandler() {

			@Override
			public void onOpenTaskSelector(OpenTaskSelectorEvent event) {
				executeLoadTaskDefinitions();
			}
		});
	}

	private void executeLoadTaskDefinitions() {
		actionManager.execute(new LoadTaskDefinitionsAction(), new AsyncCallback<LoadTaskDefinitionsResult>() {

			@Override
			public void onFailure(Throwable caught) {
				GWT.log("problem while loading task definitions", caught);
			}

			@Override
			public void onSuccess(LoadTaskDefinitionsResult result) {
				taskDefinitions = result.getTaskDefinitions();
				taskSelectorView.displayTaskDefinitions(taskDefinitions);
				taskSelectorView.appear();
			}
		});
	}

	private TaskDefinition internalGetTaskDefinitionByName(String name) {
		assert name != null;
		TaskDefinition selectedTaskDefinition = null;
		for (TaskDefinition taskDefinition : taskDefinitions) {
			if (name.equals(taskDefinition.getApplicationName())) {
				selectedTaskDefinition = taskDefinition;
				break;
			}
		}
		return selectedTaskDefinition;
	}
}
